package com.learn.learnzookeeper.os;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.I0Itec.zkclient.ZkClient;

import java.lang.instrument.Instrumentation;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * @author wangxing
 * @version 2020/7/10 11:26 Administrator
 */
public class Agent {
    private static Agent instance = new Agent();
    private static final String SERVER = "192.168.1.150:2181";
    private static final String ROOT_PATH = "/learn_manger";
    private static final String SERVER_PATH = ROOT_PATH + "/server";
    //当前服务的实际节点
    private String nodePath;
    private ZkClient zkClient;

    public static Agent getInstance() {
        return instance;
    }

    private Agent() {
    }

    // javaagent 数据监控
    public static void premain(String args, Instrumentation instrumentation) {
        Agent.getInstance().init();
    }

    public void init() {
        //创建客户端
        zkClient = new ZkClient(SERVER, 1000, 10000);
        System.out.println("zk连接成功" + SERVER);
        //创建根节点
        buildRoot();
        //创建服务临时子节点
        createServerNode();
        //启动线程更新节点状态
        startStateThread();
    }

    /**
     * 启动更新服务节点状态线程
     */
    public void startStateThread() {
        Thread stateThread = new Thread(() -> {
            while (true) {
                updateServerNode();
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "zk_stateThread");
        stateThread.setDaemon(true);
        stateThread.start();
    }

    /**
     * 更新临时节点信息
     */
    public void updateServerNode() {
        zkClient.writeData(nodePath, getOsInfo());
    }

    /**
     * 创建服务临时节点
     */
    public void createServerNode() {
        nodePath = zkClient.createEphemeralSequential(SERVER_PATH, getOsInfo());
        System.out.println("创建根服务节点");
    }

    /**
     * 获取当前操作系统信息
     *
     * @return
     */
    private String getOsInfo() {
        OsBean bean = new OsBean();
        //当前时间
        bean.lastUpdateTime = System.currentTimeMillis();
        //当前机器ip地址
        bean.ip = getLocalIp();
        //当前cpu信息
        bean.cpu = CPUMonitorCalc.getInstance().getProcessCpu();
        MemoryUsage memoryUsag = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
        //当前内存使用量
        bean.usedMemorySize = memoryUsag.getUsed() / 1024 / 1024;
        //当前内存可用量
        bean.usableMemorySize = memoryUsag.getMax() / 1024 / 1024;
        //当前进行的pid
        bean.pid = ManagementFactory.getRuntimeMXBean().getName();
        //将对象转换为JSON
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.writeValueAsString(bean);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取服务器ip信息
     *
     * @return
     */
    public static String getLocalIp() {
        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
        return addr.getHostAddress();
    }

    /**
     * 创建根节点
     */
    public void buildRoot() {
        if (!zkClient.exists(ROOT_PATH)) {
            zkClient.createPersistent(ROOT_PATH, "server");
            System.out.println("创建根节点");
        }
    }

}
